﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using Transfer.CommonUnit;
using Transfer.Utils;

namespace Transfer.SingleFloor
{
	internal class FamilyInstanceTransfer
	{
		public FamilyInstanceTransfer(ExternalCommandData cmdData, Transform matrix, double tolerance)
		{
			this.m_Revit = cmdData;
			this.m_Doc = this.m_Revit.Application.ActiveUIDocument.Document;
			this.m_CurrentViewHeight = Common.GetViewHeight(this.m_Doc, this.m_Revit.Application.ActiveUIDocument.ActiveView);
			this.m_TransformMatrix = matrix;
			this.m_Tolerance = tolerance;
			XYZ newDirection = this.GetNewDirection(XYZ.BasisX);
			XYZ newDirection2 = this.GetNewDirection(XYZ.BasisY);
			double angle = Geometry.getAngle(XYZ.Zero, newDirection);
			double angle2 = Geometry.getAngle(XYZ.Zero, newDirection2);
			if (Geometry.IsEqual(Geometry.BetweenTheAngles(angle, angle2, true), Math.PI*.5))
			{
				this.m_IsMirrored = false;
			}
			else
			{
				this.m_IsMirrored = true;
			}
			this.m_Options = this.m_Revit.Application.Application.Create.NewGeometryOptions();
			this.m_Options.IncludeNonVisibleObjects = true;
			this.m_Options.ComputeReferences = true;
			this.m_Options.View = this.m_Revit.Application.ActiveUIDocument.Document.ActiveView;
		}

		public Result TransformFamilyInstance(ICollection<ElementId> elementsIdList, int hostType)
		{
			Result result2;
			try
			{
				this.m_HostType = hostType;
				if (this.m_HostType == 0)
				{
					this.TransformGeneralFamilyInstance(elementsIdList);
				}
				Result result = this.TransformParasiticFamilyInstance(elementsIdList);
				Common.UpdateModel(this.m_Revit.Application.ActiveUIDocument, false);
				result2 = result;
			}
			catch (Exception)
			{
				result2 = Autodesk.Revit.UI.Result.Failed;
			}
			return result2;
		}

		public Result TransformTags(ICollection<ElementId> tagIdList)
		{
			foreach (ElementId elementId in tagIdList)
			{
				try
				{
					Element element = this.m_Doc.GetElement(elementId);
					if (element.GetType() == typeof(RoomTag))
					{
						this.TransformRoomTag(element as RoomTag);
					}
					else if (element.GetType() == typeof(SpaceTag))
					{
						this.TransformSpaceTag(element as SpaceTag);
					}
					else if (element.GetType() == typeof(AreaTag))
					{
						this.TransformAreaTag(element as AreaTag);
					}
					else if (element.GetType() == typeof(IndependentTag))
					{
						this.TransformIndependentTag(element as IndependentTag);
					}
				}
				catch (Exception)
				{
				}
			}
			Common.UpdateModel(this.m_Revit.Application.ActiveUIDocument, false);
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result TrasformDimensions(ICollection<ElementId> dimensionIdList)
		{
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			foreach (ElementId elementId in dimensionIdList)
			{
				try
				{
					Element element = this.m_Doc.GetElement(elementId);
					if (!(element.GetType() != typeof(Dimension)))
					{
						Dimension dimension = element as Dimension;
						if (!(null == dimension.Curve))
						{
							if (!(dimension.Curve.GetType() != typeof(Line)))
							{
								ReferenceArray references = dimension.References;
								ReferenceArray referenceArray = null;
								if (this.GetNewReferenceArray(references, ref referenceArray))
								{
									Line curve = dimension.Curve as Line;
									XYZ newPosition = this.GetNewPosition(curve.GetEndPoint(0));
									XYZ newPosition2 = this.GetNewPosition(curve.GetEndPoint(1));
									Line line = YJKLineEx.YJKGetBound(newPosition, newPosition2);
									this.m_Doc.Create.NewDimension(activeView, line, referenceArray, dimension.DimensionType);
								}
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
			Common.UpdateModel(this.m_Revit.Application.ActiveUIDocument, false);
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result TransformParasiticFamilyInstance(ICollection<ElementId> elementsIdList)
		{
			foreach (ElementId elementId in elementsIdList)
			{
				FamilyInstance familyInstance = this.m_Doc.GetElement(elementId) as FamilyInstance;
				if (familyInstance != null)
				{
					Result result = -1;
					List<ElementId> clonedFamilyInstanceIdList = new List<ElementId>();
					Element hostObj = null;
					if (this.GetHostObject(familyInstance, ref hostObj))
					{
						result = this.TransformParasiticElement(familyInstance, hostObj, ref clonedFamilyInstanceIdList);
					}
					if (result == null)
					{
						this.CloneParameters(familyInstance, clonedFamilyInstanceIdList);
					}
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result TransformGeneralFamilyInstance(ICollection<ElementId> elementsIdList)
		{
			foreach (ElementId elementId in elementsIdList)
			{
				FamilyInstance familyInstance = this.m_Doc.GetElement(elementId) as FamilyInstance;
				if (familyInstance != null)
				{
					List<ElementId> clonedFamilyInstanceIdList = this.TransformSingleFamilyInstance(familyInstance);
					this.CloneParameters(familyInstance, clonedFamilyInstanceIdList);
				}
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result TransformParasiticElement(Element element, Element hostObj, ref List<ElementId> newElementsId)
		{
			FamilyInstance familyInstance = element as FamilyInstance;
			LocationPoint locationPoint = element.Location as LocationPoint;
			if (locationPoint == null)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			XYZ newPosition = this.GetNewPosition(locationPoint.Point);
			Element element2 = this.FindNewHostObject(hostObj, ref newPosition);
			if (element2 == null)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			if (!(element.GetType() == typeof(FamilyInstance)))
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			FamilySymbol symbol = familyInstance.Symbol;
			if (symbol == null)
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			FamilyInstance familyInstance2 = null;
			try
			{
				if (this.m_HostType != 5)
				{
					ElementId elementId = familyInstance.get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM).AsElementId();
					Level level = this.m_Doc.GetElement(elementId) as Level;
					UnifiedModified.ActivateFamilySymbol(symbol);
					FamilyInstance insertInstance = this.m_Revit.Application.ActiveUIDocument.Document.Create.NewFamilyInstance(newPosition, symbol, element2, level, familyInstance.StructuralType);
					Common.UpdateModel(this.m_Revit.Application.ActiveUIDocument, false);
					familyInstance2 = this.SetInsertDirectionWithParasiticElement(insertInstance, familyInstance);
				}
				else
				{
					XYZ xyz = familyInstance.HandOrientation.CrossProduct(familyInstance.FacingOrientation);
					xyz = this.GetNewDirection(xyz);
					Reference referenceFaceOfHost = this.GetReferenceFaceOfHost(element2, newPosition, xyz);
					XYZ handOrientation = familyInstance.HandOrientation;
					UnifiedModified.ActivateFamilySymbol(symbol);
					familyInstance2 = this.m_Revit.Application.ActiveUIDocument.Document.Create.NewFamilyInstance(referenceFaceOfHost, newPosition, handOrientation, symbol);
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				return Autodesk.Revit.UI.Result.Failed;
			}
			if (familyInstance2 == null)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			newElementsId.Add(familyInstance2.Id);
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private List<ElementId> TransformSingleFamilyInstance(FamilyInstance instance)
		{
			List<ElementId> list = new List<ElementId>();
			LocationPoint locationPoint = instance.Location as LocationPoint;
			XYZ newPosition = this.GetNewPosition(locationPoint.Point);
			FamilySymbol symbol = instance.Symbol;
			if (symbol == null)
			{
				return list;
			}
			FamilyInstance familyInstance = null;
			try
			{
				ElementId elementId = instance.get_Parameter(BuiltInParameter.FAMILY_LEVEL_PARAM).AsElementId();
				Level level = this.m_Doc.GetElement(elementId) as Level;
				UnifiedModified.ActivateFamilySymbol(symbol);
				FamilyInstance insertInstance = this.m_Revit.Application.ActiveUIDocument.Document.Create.NewFamilyInstance(newPosition, symbol, level, instance.StructuralType);
				Common.UpdateModel(this.m_Revit.Application.ActiveUIDocument, false);
				familyInstance = this.SetInsertDirectionWithFamilyInstance(insertInstance, instance);
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				return list;
			}
			if (familyInstance == null)
			{
				return list;
			}
			list.Add(familyInstance.Id);
			return list;
		}

		private bool TransformRoomTag(RoomTag tag)
		{
			Room room = tag.Room;
			RoomTagType roomTagType = tag.RoomTagType;
			XYZ point = (tag.Location as LocationPoint).Point;
			Line ray = YJKLineEx.YJKGetUnBound(this.GetNewPosition(point), XYZ.BasisZ);
			Element element = this.FindNewRoomByRay(ray);
			if (element == null)
			{
				return false;
			}
			Room room2 = element as Room;
			LinkElementId linkElementId = new LinkElementId(room2.Id);
			XYZ point2 = (room2.Location as LocationPoint).Point;
			UV uv = new UV(point2.X, point2.Y);
			return this.m_Doc.Create.NewRoomTag(linkElementId, uv, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id) != null;
		}

		private bool TransformSpaceTag(SpaceTag tag)
		{
			Space space = tag.Space;
			SpaceTagType spaceTagType = tag.SpaceTagType;
			XYZ point = (tag.Location as LocationPoint).Point;
			Line ray = YJKLineEx.YJKGetUnBound(this.GetNewPosition(point), XYZ.BasisZ);
			Element element = this.FindNewSpaceByRay(ray);
			if (element == null)
			{
				return false;
			}
			Space space2 = element as Space;
			XYZ point2 = (space2.Location as LocationPoint).Point;
			UV uv = new UV(point2.X, point2.Y);
			return this.m_Doc.Create.NewSpaceTag(space2, uv, this.m_Revit.Application.ActiveUIDocument.ActiveView) != null;
		}

		private bool TransformAreaTag(AreaTag tag)
		{
			Area area = tag.Area;
			AreaTagType areaTagType = tag.AreaTagType;
			XYZ point = (tag.Location as LocationPoint).Point;
			Line ray = YJKLineEx.YJKGetUnBound(this.GetNewPosition(point), XYZ.BasisZ);
			Element element = this.FindNewAreaByRay(ray);
			if (element == null)
			{
				return false;
			}
			Area area2 = element as Area;
			XYZ point2 = (area2.Location as LocationPoint).Point;
			UV uv = new UV(point2.X, point2.Y);
			ViewPlan viewPlan = this.m_Revit.Application.ActiveUIDocument.ActiveView as ViewPlan;
			return viewPlan != null && this.m_Doc.Create.NewAreaTag(viewPlan, area2, uv) != null;
		}

		private bool TransformIndependentTag(IndependentTag tag)
		{
			Element taggedLocalElement = tag.GetTaggedLocalElement();
			Location location = taggedLocalElement.Location;
			if (location == null)
			{
				return false;
			}
			if (location.GetType() != typeof(LocationPoint))
			{
				return false;
			}
			XYZ point = (location as LocationPoint).Point;
			XYZ newPosition = this.GetNewPosition(point);
			XYZ xyz = null;
			Element element = this.FindNewHostObjectByPoint(taggedLocalElement.GetType(), newPosition, ref xyz);
			if (element == null)
			{
				return false;
			}
			XYZ tagHeadPosition = tag.TagHeadPosition;
			XYZ newPosition2 = this.GetNewPosition(tagHeadPosition);
			Autodesk.Revit.DB.View activeView = this.m_Revit.Application.ActiveUIDocument.ActiveView;
			IndependentTag independentTag = RevitVersionFuncs.NewTag(this.m_Doc, activeView, new Reference(element), tag.HasLeader, 0, tag.TagOrientation, newPosition2);
			if (independentTag == null)
			{
				return false;
			}
			independentTag.ChangeTypeId(tag.GetTypeId());
			return true;
		}

		private FamilyInstance SetInsertDirectionWithFamilyInstance(FamilyInstance insertInstance, FamilyInstance oldInstance)
		{
			FamilyInstance familyInstance = insertInstance;
			LocationPoint locationPoint = oldInstance.Location as LocationPoint;
			Line line = YJKLineEx.YJKGetUnBound((insertInstance.Location as LocationPoint).Point, XYZ.BasisZ);
			XYZ facingOrientation = oldInstance.FacingOrientation;
			XYZ newDirection = this.GetNewDirection(facingOrientation);
			double angle = Geometry.getAngle(XYZ.Zero, facingOrientation);
			double angle2 = Geometry.getAngle(XYZ.Zero, newDirection);
			double num = Geometry.BetweenTheAngles(angle, angle2, true);
			double num2 = Geometry.formatAngle(locationPoint.Rotation + num);
			bool flag = oldInstance.Mirrored;
			if (this.m_IsMirrored)
			{
				flag = !flag;
				num2 = Geometry.formatAngle(num2 + Math.PI);
			}
			if (flag)
			{
				familyInstance = this.MirrorFamilyInstanceSelf(insertInstance, true);
				if (familyInstance == null)
				{
					familyInstance = insertInstance;
				}
			}
			ElementTransformUtils.RotateElement(this.m_Doc, familyInstance.Id, line, num2);
			return familyInstance;
		}

		private FamilyInstance SetInsertDirectionWithParasiticElement(FamilyInstance insertInstance, FamilyInstance oldInstance)
		{
			LocationPoint locationPoint = insertInstance.Location as LocationPoint;
			LocationPoint locationPoint2 = oldInstance.Location as LocationPoint;
			XYZ xyz = this.GetNewDirection(oldInstance.FacingOrientation).Normalize();
			double rotation = locationPoint.Rotation;
			double num = locationPoint2.Rotation;
			bool flag = false;
			bool flag2 = false;
			if (this.m_IsMirrored)
			{
				XYZ ptOut = Geometry.RotateTo(xyz, Math.PI, XYZ.BasisZ);
				double angle = Geometry.getAngle(XYZ.Zero, ptOut);
				double num2 = Geometry.BetweenTheAngles(Geometry.getAngle(XYZ.Zero, oldInstance.FacingOrientation), angle, true);
				num = Geometry.formatAngle(num + num2);
				flag = !flag;
			}
			else
			{
				double angle2 = Geometry.getAngle(XYZ.Zero, xyz);
				double num3 = Geometry.BetweenTheAngles(Geometry.getAngle(XYZ.Zero, oldInstance.FacingOrientation), angle2, true);
				num = Geometry.formatAngle(num + num3);
			}
			if (Geometry.Lessthan_Or_Equal(Math.Abs(rotation - num), 0.0001))
			{
				if (oldInstance.Mirrored)
				{
					flag = !flag;
				}
			}
			else if (oldInstance.Mirrored)
			{
				flag2 = !flag2;
			}
			else
			{
				flag = !flag;
				flag2 = !flag2;
			}
			FamilyInstance result = insertInstance;
			if (flag && flag2)
			{
				FamilyInstance instance = this.MirrorFamilyInstanceSelf(insertInstance, true);
				result = this.MirrorFamilyInstanceSelf(instance, false);
			}
			else if (flag)
			{
				result = this.MirrorFamilyInstanceSelf(insertInstance, true);
			}
			else if (flag2)
			{
				result = this.MirrorFamilyInstanceSelf(insertInstance, false);
			}
			return result;
		}

		private FamilyInstance MirrorFamilyInstanceSelf(FamilyInstance instance, bool isHorizontal)
		{
			Plane referencePlaneWithParasiticElement;
			if (isHorizontal)
			{
				referencePlaneWithParasiticElement = this.GetReferencePlaneWithParasiticElement(instance, 0.0);
			}
			else
			{
				referencePlaneWithParasiticElement = this.GetReferencePlaneWithParasiticElement(instance, Math.PI*.5);
			}
			return MirrorOperater.MirrorParasiticElement(this.m_Doc, instance, referencePlaneWithParasiticElement, false, true);
		}

		private Element FindNewHostObject(Element hostObj, ref XYZ newPosition)
		{
			Location location = hostObj.Location;
			Element result;
			if (location.GetType() == typeof(LocationCurve))
			{
				LocationCurve locationCurve = location as LocationCurve;
				FindCurveInfo newPosition2 = this.GetNewPosition(locationCurve.Curve);
				result = this.FindNewHostObjectByCurve(hostObj.GetType(), newPosition2, ref newPosition);
			}
			else if (location.GetType() == typeof(LocationPoint))
			{
				LocationPoint locationPoint = location as LocationPoint;
				XYZ newPosition3 = this.GetNewPosition(locationPoint.Point);
				result = this.FindNewHostObjectByPoint(hostObj.GetType(), newPosition3, ref newPosition);
			}
			else
			{
				Line ray = YJKLineEx.YJKGetUnBound(newPosition, XYZ.BasisZ);
				result = this.FindNewHostObjectByRay(hostObj.GetType(), ray);
			}
			return result;
		}

		private Element FindNewHostObjectByPoint(Type hostObjectType, XYZ newLocation, ref XYZ position)
		{
			IList<Element> elements = new FilteredElementCollector(this.m_Doc, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id).OfClass(hostObjectType).ToElements();
			List<Element> list = new List<Element>();
			this.FilterHostObjectByView(elements, ref list);
			double val = this.m_Tolerance;
			Element element = null;
			XYZ xyz = null;
			foreach (Element element2 in list)
			{
				LocationPoint locationPoint = element2.Location as LocationPoint;
				if (locationPoint != null)
				{
					double num = locationPoint.Point.DistanceTo(newLocation);
					if (locationPoint.Point.IsAlmostEqualTo(newLocation))
					{
						return element2;
					}
					if (Geometry.Lessthan_Or_Equal(num, val))
					{
						val = num;
						xyz = locationPoint.Point;
						element = element2;
					}
				}
			}
			if (element != null)
			{
				position += xyz - newLocation;
			}
			return element;
		}

		private Element FindNewHostObjectByCurve(Type hostObjectType, FindCurveInfo newLocation, ref XYZ position)
		{
			IList<Element> elements = new FilteredElementCollector(this.m_Doc, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id).OfClass(hostObjectType).ToElements();
			List<Element> list = new List<Element>();
			this.FilterHostObjectByView(elements, ref list);
			double val = this.m_Tolerance;
			Element element = null;
			FindCurveInfo rhs = null;
			foreach (Element element2 in list)
			{
				LocationCurve locationCurve = element2.Location as LocationCurve;
				if (locationCurve != null)
				{
					FindCurveInfo findCurveInfo = new FindCurveInfo(locationCurve.Curve);
					if (findCurveInfo.IsOverlap(newLocation, position))
					{
						return element2;
					}
					double num = 0.0;
					if (findCurveInfo.IsParallel2ndOverlap(newLocation, position, ref num) && Geometry.Lessthan_Or_Equal(num, val))
					{
						val = num;
						rhs = findCurveInfo;
						element = element2;
					}
				}
			}
			if (element != null)
			{
				position += newLocation.GetOffset(rhs, position);
			}
			return element;
		}

		private Element FindNewHostObjectByRay(Type hostObjectType, Line ray)
		{
			IList<Element> elements = new FilteredElementCollector(this.m_Doc, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id).OfClass(hostObjectType).ToElements();
			return this.FindNewHostObjectByRay(elements, ray);
		}

		private Element FindNewRoomByRay(Line ray)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id);
			RoomFilter roomFilter = new RoomFilter();
			filteredElementCollector.WherePasses(roomFilter);
			IList<Element> elements = filteredElementCollector.ToElements();
			return this.FindNewHostObjectByRay(elements, ray);
		}

		private Element FindNewSpaceByRay(Line ray)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id);
			SpaceFilter spaceFilter = new SpaceFilter();
			filteredElementCollector.WherePasses(spaceFilter);
			IList<Element> elements = filteredElementCollector.ToElements();
			return this.FindNewHostObjectByRay(elements, ray);
		}

		private void FilterHostObjectByView(IList<Element> elements, ref List<Element> filteredEles)
		{
			double elevation = this.m_Revit.Application.ActiveUIDocument.ActiveView.GenLevel.Elevation;
			double val = elevation + this.m_CurrentViewHeight;
			foreach (Element element in elements)
			{
				BoundingBoxXYZ boundingBoxXYZ = element.get_BoundingBox(this.m_Revit.Application.ActiveUIDocument.ActiveView);
				if (!Geometry.Lessthan_Or_Equal(boundingBoxXYZ.Max.Z, elevation) && !Geometry.Greaterthan_Or_Equal(boundingBoxXYZ.Min.Z, val))
				{
					filteredEles.Add(element);
				}
			}
		}

		private Element FindNewAreaByRay(Line ray)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc, this.m_Revit.Application.ActiveUIDocument.ActiveView.Id);
			AreaFilter areaFilter = new AreaFilter();
			filteredElementCollector.WherePasses(areaFilter);
			IList<Element> elements = filteredElementCollector.ToElements();
			return this.FindNewHostObjectByRay(elements, ray);
		}

		private Element FindNewHostObjectByRay(IList<Element> elements, Line ray)
		{
			foreach (Element element in elements)
			{
				IEnumerator<GeometryObject> enumerator2 = element.get_Geometry(this.m_Options).GetEnumerator();
				List<GeometryObject> list = new List<GeometryObject>();
				while (enumerator2.MoveNext())
				{
					GeometryObject item = enumerator2.Current;
					list.Add(item);
				}
				foreach (GeometryObject geometryObject in list)
				{
					Solid solid = geometryObject as Solid;
					if (!(solid == null))
					{
						foreach (object obj in solid.Faces)
						{
							Face face = (Face)obj;
							if (!(face.GetType() != typeof(PlanarFace)))
							{
								PlanarFace planarFace = face as PlanarFace;
								IntersectionResultArray intersectionResultArray;
								if (planarFace.ComputeNormal(new UV(planarFace.Origin.X, planarFace.Origin.Y)).IsAlmostEqualTo(XYZ.BasisZ) && p(int)lanarFace.Intersect(ray, out intersectionResultArray) == 8)
								{
									return element;
								}
							}
						}
					}
				}
			}
			return null;
		}

		private Reference GetReferenceFaceOfHost(Element host, XYZ pos, XYZ dir)
		{
			IEnumerator<GeometryObject> enumerator = host.get_Geometry(this.m_Options).GetEnumerator();
			List<GeometryObject> list = new List<GeometryObject>();
			while (enumerator.MoveNext())
			{
				GeometryObject item = enumerator.Current;
				list.Add(item);
			}
			double val = this.m_Tolerance;
			Reference result = null;
			foreach (GeometryObject geometryObject in list)
			{
				Solid solid = geometryObject as Solid;
				if (!(solid == null))
				{
					foreach (object obj in solid.Faces)
					{
						Face face = (Face)obj;
						if (!(face.GetType() != typeof(PlanarFace)))
						{
							PlanarFace planarFace = face as PlanarFace;
							IntersectionResult intersectionResult = planarFace.Project(pos);
							if (intersectionResult != null && (planarFace.FaceNormal().IsAlmostEqualTo(dir) || planarFace.FaceNormal().IsAlmostEqualTo(-dir)))
							{
								if (Geometry.IsEqual(intersectionResult.Distance, 0.0))
								{
									return planarFace.Reference;
								}
								if (Geometry.Lessthan_Or_Equal(intersectionResult.Distance, val))
								{
									val = intersectionResult.Distance;
									result = planarFace.Reference;
								}
							}
						}
					}
				}
			}
			return result;
		}

		private XYZ GetNewPosition(XYZ ptLocation)
		{
			XYZ xyz = Geometry.TransformPoint(ptLocation, this.m_TransformMatrix);
			return new XYZ(xyz.X, xyz.Y, ptLocation.Z);
		}

		private XYZ GetNewDirection(XYZ ptDirection)
		{
			XYZ newPosition = this.GetNewPosition(XYZ.Zero);
			return this.GetNewPosition(ptDirection) - newPosition;
		}

		private FindCurveInfo GetNewPosition(Curve curve)
		{
			FindCurveInfo findCurveInfo = new FindCurveInfo(curve);
			XYZ newPosition = this.GetNewPosition(findCurveInfo.StartPoint);
			XYZ newPosition2 = this.GetNewPosition(findCurveInfo.EndPoint);
			double bulge = 0.0;
			FindCurveInfo result;
			if (findCurveInfo.IsArc)
			{
				XYZ ptLocation = null;
				Geometry.GetCenterWithBulge(findCurveInfo.StartPoint, findCurveInfo.EndPoint, findCurveInfo.Bulge, ref ptLocation);
				XYZ newPosition3 = this.GetNewPosition(ptLocation);
				if (this.m_IsMirrored)
				{
					bulge = Geometry.GetBulge(newPosition2, newPosition, newPosition3, true);
					result = new FindCurveInfo(newPosition2, newPosition, bulge);
				}
				else
				{
					bulge = Geometry.GetBulge(newPosition, newPosition2, newPosition3, true);
					result = new FindCurveInfo(newPosition, newPosition2, bulge);
				}
			}
			else
			{
				result = new FindCurveInfo(newPosition, newPosition2, bulge);
			}
			return result;
		}

		private bool GetNewReferenceArray(ReferenceArray refArray, ref ReferenceArray newRefArray)
		{
			foreach (object obj in refArray)
			{
				Reference reference = (Reference)obj;
				ElementId elementId = reference.ElementId;
				Element element = this.m_Doc.GetElement(elementId);
				if (reference.GlobalPoint != null)
				{
					XYZ newPosition = this.GetNewPosition(reference.GlobalPoint);
					Element element2 = this.FindNewHostObject(element, ref newPosition);
					if (element2 != null)
					{
						Reference newReferenceArray = this.GetNewReferenceArray(element2, reference);
						if (newReferenceArray != null)
						{
							newRefArray.Append(newReferenceArray);
						}
					}
				}
			}
			return newRefArray.Size >= 2;
		}

		private Reference GetNewReferenceArray(Element newElement, Reference reference)
		{
			Reference result = null;
			if ((int)reference.ElementReferenceType != 1)
			{
				ElementReferenceType elementReferenceType = reference.ElementReferenceType;
			}
			return result;
		}

		private Plane GetReferencePlaneWithParasiticElement(FamilyInstance instance, double rotateAngle)
		{
			Plane result = null;
			XYZ facingOrientation = instance.FacingOrientation;
			if (facingOrientation == null)
			{
				return result;
			}
			LocationPoint locationPoint = instance.Location as LocationPoint;
			if (locationPoint == null)
			{
				return result;
			}
			XYZ point = locationPoint.Point;
			return RevitVersionFuncs.CreatePlanByNormalAndOrigin(Geometry.RotateTo(facingOrientation, rotateAngle, XYZ.BasisZ), point);
		}

		private bool GetHostObject(Element element, ref Element hostObject)
		{
			Element element2 = null;
			FamilyInstance familyInstance = element as FamilyInstance;
			if (familyInstance != null)
			{
				element2 = familyInstance.Host;
			}
			if (element2 == null)
			{
				return false;
			}
			hostObject = element2;
			return true;
		}

		private void CloneParameters(FamilyInstance instance, List<ElementId> clonedFamilyInstanceIdList)
		{
			foreach (ElementId elementId in clonedFamilyInstanceIdList)
			{
				FamilyInstance familyInstance = this.m_Doc.GetElement(elementId) as FamilyInstance;
				if (familyInstance != null)
				{
					ParameterCopier.CopyParameters(instance, ref familyInstance);
				}
			}
		}

		private ExternalCommandData m_Revit;

		private Document m_Doc;

		private double m_CurrentViewHeight = -1.0;

		private Transform m_TransformMatrix;

		private bool m_IsMirrored;

		private int m_HostType;

		private Options m_Options;

		private double m_Tolerance;
	}
}
